package com.yzy.fly.environment;

import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.google.common.collect.Lists;
import com.yzy.fly.api.annotation.ApiDoc;
import com.yzy.fly.api.annotation.ApiDocOrder;
import com.yzy.fly.api.annotation.ApiOperation;
import com.yzy.fly.bean.FlyCustomBeanDefinitionRegistryPostProcessor;
import com.yzy.fly.config.SpringContextUtil;
import com.yzy.fly.kernel.controller.FlyConstant;
import com.yzy.fly.kernel.controller.FlyNoneController;
import com.yzy.fly.domain.RestMessage;
import com.yzy.fly.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.ibatis.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.*;

@ApiDoc(desc="运行环境")
@Slf4j
@RestController
@RequestMapping("/env")
public class FlyEnvironmentController extends FlyNoneController {

//    private static Log log = LogFactory.getLog(FlyEnvironmentController.class);
    @Autowired
    @Lazy
    private FlyCustomBeanDefinitionRegistryPostProcessor flyCustomBeanDefinitionRegistryPostProcessor;

    @Autowired
    @Lazy
    private MybatisPlusProperties mybatisPlusProperties;

    @ApiDocOrder(100)
    @ApiOperation(value = "获取bean定义信息",notes = "获取bean定义信息",author="yinzhiyuan")
    @RequestMapping(value = "/beans", method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public RestMessage query(){
        long statTime = System.currentTimeMillis();
        List<BeanDefinitionInfo> beanDefinitionInfoList = flyCustomBeanDefinitionRegistryPostProcessor.getBeanDefinitionInfoList();
        String json = JsonUtil.prettyFormat(beanDefinitionInfoList);
//        log.info(json);
        long endTime = System.currentTimeMillis();
        return RestMessage.success("查询成功",beanDefinitionInfoList,(endTime-statTime));
    }

    @ApiDocOrder(200)
    @ApiOperation(value = "获取mapper定义信息",notes = "获取mapper定义信息",author="yinzhiyuan")
    @RequestMapping(value = "/mappers", method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public RestMessage mybatisPlusProperties(){
        long statTime = System.currentTimeMillis();

        MybatisPlusProperties.CoreConfiguration configuration = mybatisPlusProperties.getConfiguration();
        Collection<Class<?>> mappers = null;
//        Collection<Class<?>> mappers = configuration.getMapperRegistry().getMappers();
        List<MapperDefinitionInfo> mapperDefinitionInfos = Lists.newArrayListWithCapacity(0);
        if (CollectionUtils.isNotEmpty(mappers)) {
            for (Class<?> mapper : mappers) {
//                System.out.println(mapper.getName());
                MapperDefinitionInfo mapperDefinitionInfo = new MapperDefinitionInfo();
                mapperDefinitionInfo.setBeanClassName(mapper.getName());
                mapperDefinitionInfo.setName(mapper.getSimpleName());
                mapperDefinitionInfos.add(mapperDefinitionInfo);
                Method[] methods = mapper.getMethods();
                if (ArrayUtils.isNotEmpty(methods)) {
                    List<String> sqls = mapperDefinitionInfo.getSqls();
                    for (int i = 0; i < methods.length; i++) {
                        Method method = methods[i];
                        String[] sqlArray = null;
                        Select select = method.getAnnotation(Select.class);
                        Update update = method.getAnnotation(Update.class);
                        Delete delete = method.getAnnotation(Delete.class);
                        Insert insert = method.getAnnotation(Insert.class);
                        if(null != select){
                            sqlArray = select.value();
                        } else if(null != update){
                            sqlArray = update.value();
                        } else if(null != delete){
                            sqlArray = delete.value();
                        } else if(null != insert){
                            sqlArray = insert.value();
                        } else {
                            //如果没有设置注解

                        }
                        StringBuffer sql = new StringBuffer("");
                        if (ArrayUtils.isNotEmpty(sqlArray)) {
                            for (int j = 0; j < sqlArray.length; j++) {
                                String subSql = sqlArray[j];
                                sql.append(subSql).append("\n");
                            }
                        }
                        sqls.add(sql.toString());
                    }
                }
            }
        }
//        Configuration configuration = sqlSessionFactory.getConfiguration();
//        Collection<MappedStatement> mappedStatements = configuration.getMappedStatements();
//        List<MappedStatement> list = Lists.newArrayList(mappedStatements);
//        for (int i = 0; i < list.size(); i++) {
//            MappedStatement mappedStatement =  list.get(i);
//            String mappedStatementId = mappedStatement.getId();
//            SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
//            ParameterMap parameterMap = mappedStatement.getParameterMap();
//            Class<?> type = parameterMap.getType();
//            Object instance = null;
//            if (type != null) {
//                System.out.println(type.getName());
//                if(type != int.class){
//                    instance = type.newInstance();
//                }
//            }
//            SqlSource sqlSource = mappedStatement.getSqlSource();
//            try{
//                System.out.println(mappedStatement.getBoundSql(instance).getSql());
//            } catch (Exception e){
////                    e.printStackTrace();
//            }
//        }

        long endTime = System.currentTimeMillis();
        return RestMessage.success("查询成功",mapperDefinitionInfos,(endTime-statTime));
    }

    @Deprecated
    @ApiDocOrder(400)
    @ApiOperation(value = "容器注册bean",notes = "向当前容器注册bean对象",author="yinzhiyuan")
    @RequestMapping("/registerBean")
    public RestMessage registerBean(String beanName){
        long statTime = System.currentTimeMillis();
        try {
            // 注册 bean
            Object beanObject = null;
            try {
                if (SpringContextUtil.containsBean(beanName)) {
                    SpringContextUtil.unregisterBean(beanName);
                }
                SpringContextUtil.registerBean(beanName, beanObject);
            } catch (Exception e) {
                log.warn("register {beanName} error ", beanName, e);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return RestMessage.success("注册失败",null,0);
        }
        long endTime = System.currentTimeMillis();
        return RestMessage.success("注册成功",null,(endTime-statTime));
    }

    @Deprecated
    @ApiDocOrder(500)
    @ApiOperation(value = "容器移除bean",notes = "当前容器移除bean对象",author="yinzhiyuan")
    @RequestMapping("/unregisterBean")
    public RestMessage unregisterBean(String beanName){
        long statTime = System.currentTimeMillis();
        try {
            try {
                if (SpringContextUtil.containsBean(beanName)) {
                    SpringContextUtil.unregisterBean(beanName);
                }
            } catch (Exception e) {
                log.warn("unregisterBean {beanName} error ", beanName, e);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return RestMessage.success("移除注册失败",null,0);
        }
        long endTime = System.currentTimeMillis();
        return RestMessage.success("移除注册成功",null,(endTime-statTime));
    }

    @Override
    public String getType() {
        return FlyConstant.FLY_CORE;
    }
}
